package com.study.group.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @Description 时间工具类
 * @Author      yanghanwei
 * @Mail        yanghanwei@geotmt.com
 * @Date        2019/3/14 17:27
 * @Version     v1
 **/
public class GeoDateUtils {

    private static final Logger logger = LoggerFactory.getLogger(GeoDateUtils.class);

    public static final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    public static final String DATE_FORMAT2 = "yyyyMMdd";
    public static final String DATE_FORMAT3 = "yyyyMMddHHmmss";

    private static final String TEXT = "text";


    /**
     * 加减日期
     * @param date
     * @param num
     * @return
     */
    public static Date getDate(Date date, int num){
        Date time = null;
        if(null != date){
            time = new Date(date.getTime() + num * 1000L * 60 * 60 * 24);
        }
        return time;
    }

    /**
     * 获取正天的 时间戳
     * @param date
     * @return
     */
    public static Long getLongDate(Date date) {
        Long data = 0L;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(date);
        try{
            data = sdf.parse(format).getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * yyyy-MM-dd HH:mm:ss 字符串转日期
     * @param date
     * @return
     */
    public static Date getStringToDate(String date){
        SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //加上时间
        try {
            Date dat = sDateFormat.parse(date);
            return dat;
        } catch(ParseException px) {
            px.printStackTrace();
            return null;
        }
    }

    public static Long getDiffDaysForNow(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        Long diff = 0L;
        try {
            long timeBefore = sdf.parse(sdf.format(date)).getTime();
            long timeNow = sdf.parse(sdf.format(new Date(System.currentTimeMillis()))).getTime();
            if(timeBefore <= timeNow){
                diff = (timeNow - timeBefore) / (1000L * 60 * 60 * 24) + 1;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return diff;
    }

    /**
     * yyyy-MM-dd HH:mm:ss 日期转字符串
     * @param date
     * @return
     */
    public static String getDateStr(Date date){
        String format = "";
        if(null != date){
            SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT);
            format = sdf.format(date);
        }
        return  format;
    }

    /**
     * 根据传入格式化转化日期为字符串
     * @param date
     * @param partten
     * @return
     */
    public static String getDateStr(Date date,String partten){
        String format = "";
        if(null != date){
            SimpleDateFormat sdf = new SimpleDateFormat(partten);
            format = sdf.format(date);
        }
        return  format;
    }

    public static String getDateStr(Long dateTime,String timeFormat){
        String format = "";
        if(null != dateTime){
            SimpleDateFormat sdf = new SimpleDateFormat(timeFormat);
            format = sdf.format(new Date(dateTime));
        }
        return  format;
    }

    /**
     * 获取原时间戳
     * @param reverseTime
     * @return
     */
    public static Long recoverReverseTime(Long reverseTime){
        long longTime = Long.MAX_VALUE - reverseTime;
        return longTime/1000000;
    }

    /**
     * 日期转换为字符串 yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String getShotDate(Date date) {
        if (date == null){
            return "";
        }
        return dateStr(date, "yyyy-MM-dd");
    }

    /**
     * 日期转换为字符串 格式自定义
     *
     * @param date
     * @param f
     * @return
     */
    public static String dateStr(Date date, String f) {
        if (date == null){
            return "";
        }
        SimpleDateFormat format = new SimpleDateFormat(f);
        String str = format.format(date);
        return str;
    }

    /**
     *
     * 字符串转换为对应日期
     *
     * @param timeString
     * @param format
     * @return
     */
    public static Date stringToDate(String timeString, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = simpleDateFormat.parse(timeString);
        } catch (Exception e) {
        }
        return date;
    }

    /**
     * 获取穿入日期的前num 天
     * @param date
     * @return
     */
    public static Date getPreDay(Date date,int num){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, num);
        Date time = calendar.getTime();
        String dateStr = GeoDateUtils.dateStr(time, GeoDateUtils.DATE_FORMAT2);
        return  GeoDateUtils.getDateByStrTime(dateStr, GeoDateUtils.DATE_FORMAT2);
    }

    /**
     * 获得当前日期
     * @return
     */
    public static Date getNow() {
        Calendar cal = Calendar.getInstance();
        Date currDate = cal.getTime();
        return currDate;
    }

    /**
     * 获得当前日期，精确到毫秒
     * @return
     */
    public static Timestamp getNowInMillis() {
        Timestamp timeStamep = new Timestamp(getNow().getTime());
        return timeStamep;
    }

    public static Date getDateByStrTime(String dateStr, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            return sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 计算两个日期之间相差的天数
     * @param date1
     * @param date2
     * @return  date1>date2时结果<0,  date1=date2时结果=0, date2>date1时结果>0
     */
    public static int daysBetween(Date date1, Date date2, String format){
        DateFormat sdf=new SimpleDateFormat(format);
        Calendar cal = Calendar.getInstance();
        try {
            Date d1 = sdf.parse(GeoDateUtils.dateStr(date1, format));
            Date d2 = sdf.parse(GeoDateUtils.dateStr(date2, format));
            cal.setTime(d1);
            long time1 = cal.getTimeInMillis();
            cal.setTime(d2);
            long time2 = cal.getTimeInMillis();
            return Integer.parseInt(String.valueOf((time2 - time1) / 86400000L));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 计算两个日期之间相差的小时数
     * @param date1
     * @param date2
     * @return
     */
    public static int hoursBetween(Date date1, Date date2) {
        DateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Calendar cal = Calendar.getInstance();
        try {
            Date d1 = sdf.parse(GeoDateUtils.dateStr(date1, "yyyyMMdd"));
            Date d2 = sdf.parse(GeoDateUtils.dateStr(date2, "yyyyMMdd"));
            cal.setTime(d1);
            cal.setTime(d1);
            long time1 = cal.getTimeInMillis();
            cal.setTime(d2);
            long time2 = cal.getTimeInMillis();
            return Integer.parseInt(String.valueOf((time2 - time1) / 3600000L));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 计算两个日期相差的时间
     */
    public static void getBetweenDate () {
        String dateStart = "2017111520";
        String dateStop = "2017111620";
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHH");
        Date d1 = null;
        Date d2 = null;
        try {
            d1 = format.parse(dateStart);
            d2 = format.parse(dateStop);

            //毫秒ms
            long diff = d2.getTime() - d1.getTime();

            long diffSeconds = diff / 1000 % 60;
            long diffMinutes = diff / (60 * 1000) % 60;
            long diffHours = diff / (60 * 60 * 1000) % 24;
            long diffDays = diff / (24 * 60 * 60 * 1000);

            System.out.print("两个时间相差：");
            System.out.print(diffDays + " 天, ");
            System.out.print(diffHours + " 小时, ");
            System.out.print(diffMinutes + " 分钟, ");
            System.out.print(diffSeconds + " 秒.");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    /**
     * 计算两个日期之间相差的小时数
     * @param date1
     * @param date2
     * @return  date1>date2时结果<0,  date1=date2时结果=0, date2>date1时结果>0
     */
    public static int hoursBetweenByDateStr(Date date1, Date date2) {
        DateFormat sdf=new SimpleDateFormat("yyyyMMddHH");
        Calendar cal = Calendar.getInstance();
        try {
            Date d1 = sdf.parse(GeoDateUtils.dateStr(date1,"yyyyMMddHH"));
            Date d2 = sdf.parse(GeoDateUtils.dateStr(date2,"yyyyMMddHH"));
            cal.setTime(d1);
            long time1 = cal.getTimeInMillis();
            cal.setTime(d2);
            long time2 = cal.getTimeInMillis();
            return Integer.parseInt(String.valueOf(((time2 - time1) / 3600000L)));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 计算两个日期之间相差的分钟数
     * @param date1
     * @param date2
     * @return  date1>date2时结果<0,  date1=date2时结果=0, date2>date1时结果>0
     */
    public static int minuteBetweenByDateStr(Date date1, Date date2) {
        DateFormat sdf=new SimpleDateFormat("yyyyMMddHHmm");
        Calendar cal = Calendar.getInstance();
        try {
            Date d1 = sdf.parse(GeoDateUtils.dateStr(date1,"yyyyMMddHHmm"));
            Date d2 = sdf.parse(GeoDateUtils.dateStr(date2,"yyyyMMddHHmm"));
            cal.setTime(d1);
            long time1 = cal.getTimeInMillis();
            cal.setTime(d2);
            long time2 = cal.getTimeInMillis();
            return Integer.parseInt(String.valueOf(((time2 - time1) / 60000L)));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 计算两个日期之间相差的秒数
     * @param date1
     * @param date2
     * @return  date1>date2时结果<0,  date1=date2时结果=0, date2>date1时结果>0
     */
    public static int secondBetweenByDateStr(Date date1, Date date2) {
        DateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
        Calendar cal = Calendar.getInstance();
        try {
            Date d1 = sdf.parse(GeoDateUtils.dateStr(date1, "yyyyMMddHHmmss"));
            Date d2 = sdf.parse(GeoDateUtils.dateStr(date2, "yyyyMMddHHmmss"));
            cal.setTime(d1);
            long time1 = cal.getTimeInMillis();
            cal.setTime(d2);
            long time2 = cal.getTimeInMillis();
            return Integer.parseInt(String.valueOf(((time2 - time1) / 1000L)));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 时长转换为拼接的字符串，如 79s => 0,1,19
     * @param timeLong
     * @return
     */
    public static String lengthOfTimeToStr(Long timeLong,String type){
        try{
            String dateStr = "";
            logger.info("active method is DateUtil => lengthOfTimeToStr ");
            if (null == timeLong){
                throw new Exception("传入时长为null");
            }
            Long hour = timeLong / (1000L * 60 * 60);
            Long minute = (timeLong - hour * (1000L * 60 * 60)) / (1000L * 60);
            Long second = (timeLong - hour * (1000L * 60 * 60) - minute * (1000L * 60)) / 1000L;
            if(TEXT.equals(type)){
                dateStr += (hour == 0 ? "": hour + "小时") + (minute == 0 ? "" : minute + "分") + (second == 0 ? "1秒" : second +"秒");
            }else{
                dateStr += (hour <10 ? "0"+hour+":" : hour + ":") + (minute <10 ? "0"+minute + ":" : minute + ":")
                        + (second < 10 ? "0" + second : second);
            }
            return dateStr;
        }catch (Exception e){
            logger.info("DateUtil => lengthOfTimeToStr is exception :"+e);
            return "";
        }
    }

    /**
     * 获得某年某月的天数
     * @param year
     * @param month
     * @return
     */
    public static int getDaysByYearMonth(int year,int month) {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.YEAR, year);
        a.set(Calendar.MONTH, month - 1);
        a.set(Calendar.DATE, 1);
        a.roll(Calendar.DATE, -1);
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    public static String getSecond(Long timeLong){
        try{
            int ceil = 0;
            logger.info("active method is DateUtil => getSecond ");
            if (null == timeLong){
                throw new Exception("传入时长为null");
            }
            ceil = (int)Math.ceil((float)timeLong / 1000/60);
            return ceil+"";
        }catch (Exception e){
            logger.info("DateUtil => lengthOfTimeToStr is exception :"+e);
            return "";
        }
    }

    /**
     * 判断此年是否为闰年
     * @param year
     * @return
     */
    public static Boolean isLeapYear(Integer year) {
        Boolean isTrue = false;
        if (year % 4 == 0 && year % 100 != 0){
            isTrue = true;
        } else
        if(year % 400 == 0){
            isTrue = true;
        }
        return isTrue;
    }

    //将时间插入dateList
    private static List<String> addData2DateList(Integer startYear, Integer startMonth, Integer startDay, Integer endYear, Integer endMonth, Integer endDay, Integer dayNum){
        List<String> dateList = new ArrayList<>();
        for (int i = startDay; i <= dayNum; i++) {
            String dateStr = startYear+"年";
            if (startMonth < 10) {
                dateStr+="0";
            }
            if (i < 10) {
                dateList.add(dateStr+startMonth+"月0"+i+"日");
            } else {
                dateList.add(dateStr+startMonth+"月"+i+"日");
            }
        }
        for (int i = 1; i <= endDay; i++) {
            String dateStr = endYear+"年";
            if (endMonth < 10) {
                dateStr+="0";
            }
            if (i < 10) {
                dateList.add(dateStr+endMonth+"月0"+i+"日");
            } else {
                dateList.add(dateStr+endMonth+"月"+i+"日");
            }
        }
        return dateList;
    }

    /**
     * 得到开始日期到结束日期的dateList
     * @param startTimeStr
     * @param endTimeStr
     * @return
     */
    public static List<String> getDayListBetweenStartAndEnd(String startTimeStr,String endTimeStr) {
        //时间集合
        List<String> dateList = null;
        Integer startYear = Integer.valueOf(startTimeStr.substring(0,4));
        Integer startMonth = Integer.valueOf(startTimeStr.substring(5,7));
        Integer startDay = Integer.valueOf(startTimeStr.substring(8,10));
        Integer endYear = Integer.valueOf(endTimeStr.substring(0,4));
        Integer endMonth = Integer.valueOf(endTimeStr.substring(5,7));
        Integer endDay = Integer.valueOf(endTimeStr.substring(8,10));

        List<Integer> bigMonth = new ArrayList<>();
        bigMonth.add(1);
        bigMonth.add(3);
        bigMonth.add(5);
        bigMonth.add(7);
        bigMonth.add(8);
        bigMonth.add(10);
        bigMonth.add(12);

        List<Integer> smallMonth = new ArrayList<>();
        smallMonth.add(4);
        smallMonth.add(6);
        smallMonth.add(9);
        smallMonth.add(11);
        //前后时间在同一月
        if (startMonth.equals(endMonth)) {
            dateList = new ArrayList<>();
            for (int i = startDay; i <= endDay; i++) {
                if (i < 10) {
                    if (startMonth < 10) {
                        dateList.add(startYear+"年0"+startMonth+"月0"+i+"日");
                    } else {
                        dateList.add(startYear+"年"+startMonth+"月0"+i+"日");
                    }
                } else {
                    if (startMonth < 10) {
                        dateList.add(startYear+"年0"+startMonth+"月"+i+"日");
                    } else {
                        dateList.add(startYear+"年"+startMonth+"月"+i+"日");
                    }
                }
            }
        } else {
            //前后时间不在同一月
            //判断月份是否是二月
            if (startMonth == 2) {
                //判断年份是否为闰年
                if (isLeapYear(startYear)) {
                    //为闰月，天数为29天
                    dateList = addData2DateList(startYear,startMonth,startDay,endYear,endMonth,endDay,29);
                } else {
                    dateList = addData2DateList(startYear,startMonth,startDay,endYear,endMonth,endDay,28);
                }
            }
            //判断开始时间是否是大月
            if (bigMonth.contains(startMonth)) {
                dateList = addData2DateList(startYear,startMonth,startDay,endYear,endMonth,endDay,31);
            }
            //判断开始时间是否是小月
            if (smallMonth.contains(startMonth)) {
                dateList = addData2DateList(startYear,startMonth,startDay,endYear,endMonth,endDay,30);
            }
        }

        return dateList;
    }


    /**
     * 获得指定日期的前一天
     * @param specifiedDay
     * @return
     * @throws Exception
     */
    public static String getSpecifiedDayBefore(String specifiedDay){
//SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        Date date=null;
        try {
            date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        c.setTime(date);
        int day=c.get(Calendar.DATE);
        c.set(Calendar.DATE,day-1);

        String dayBefore=new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
        return dayBefore;
    }

}
